#ifndef UNITTESTCORE_H_INCLUDED
#define UNITTESTCORE_H_INCLUDED

#include "Assertions.h"

namespace CEngine {

namespace UnitTestNothingToSeeHere {
    extern const U32 MAX_TESTS;
}

template<class T, class T2> void
UnitTest::test(const U8 groupID, const CHAR* testName, const T& result, const T2& expectedResult, const TestType type) {
    ASSERT(testCount <= UnitTestNothingToSeeHere::MAX_TESTS);

    if(groupID >= groupCount) {
        return;
    }

    U32 length = 1;

    for (U32 i = 0; testName[i] != '\0'; ++i) {
        ++length;
    }

    tests[testCount].testName = (CHAR*)stack.alloc(length);
    tests[testCount].groupID = groupID;
    switch(type) {
        case Equal:
            if(result == expectedResult) {
                tests[testCount].passed = true;
            }
            break;
        case NotEqual:
            if(result != expectedResult) {
                tests[testCount].passed = true;
            }
            break;
        case LessThan:
            if(result < expectedResult) {
                tests[testCount].passed = true;
            }
            break;
        case GreaterThan:
            if(result > expectedResult) {
                tests[testCount].passed = true;
            }
            break;
        case LessOrEqual:
            if(result <= expectedResult) {
                tests[testCount].passed = true;
            }
            break;
        case GreaterOrEqual:
            if(result >= expectedResult) {
                tests[testCount].passed = true;
            }
            break;
        case Null:
            if(!result) {
                tests[testCount].passed = true;
            }
            break;
        case NotNull:
            if(result) {
                tests[testCount].passed = true;
            }
            break;
    }



    CHAR* address = tests[testCount].testName;

    for (U32 i = 0; i < length; ++i) {
        address[i] = testName[i];
    }
    ++testCount;
}

template<class T> void
UnitTest::test(const U8 groupID, const CHAR* testName, const T& result, const TestType type) {
    ASSERT(testCount <= UnitTestNothingToSeeHere::MAX_TESTS);

    if(groupID >= groupCount) {
        return;
    }

    U32 length = 1;

    for (U32 i = 0; testName[i] != '\0'; ++i) {
        ++length;
    }

    tests[testCount].testName = (CHAR*)stack.alloc(length);
    tests[testCount].groupID = groupID;
    switch(type) {
        case Null:
            if(!result) {
                tests[testCount].passed = true;
            }
            break;
        case NotNull:
            if(result) {
                tests[testCount].passed = true;
            }
            break;
        default:
            ///type must be Null or NotNull!
            ASSERT(false);
    }



    CHAR* address = tests[testCount].testName;

    for (U32 i = 0; i < length; ++i) {
        address[i] = testName[i];
    }
    ++testCount;
}

}

#endif // UNITTESTCORE_H_INCLUDED
